package com.atguigu.gmall.product.service.impl;

import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.JSONs;
import com.atguigu.gmall.product.entity.BaseCategory1;
import com.atguigu.gmall.product.vo.CategoryPath;
import com.atguigu.gmall.product.vo.CategoryTreeVo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.gmall.product.service.BaseCategory1Service;
import com.atguigu.gmall.product.mapper.BaseCategory1Mapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* @author lfy
* @description 针对表【base_category1(一级分类表)】的数据库操作Service实现
* @createDate 2023-07-11 15:27:09
*/
@Service
public class BaseCategory1ServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1>
    implements BaseCategory1Service{

    @Autowired
    BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    StringRedisTemplate redisTemplate;


    /**
     * 引入完整缓存逻辑
     *
     * @return
     */
    @Override
    public List<CategoryTreeVo> getCategoryTree() {
        //TODO 等待改造
        return baseCategory1Mapper.getCategoryTree();
    }

    /**
     * 不能直接放给数据库
     * @return
     */
    public List<CategoryTreeVo> getCategoryTreeV1() {
        //1、先查缓存
        String categorytreeJson = redisTemplate.opsForValue().get(RedisConst.INDEXPAGE_CATEGORY_TREE_KEY);
        if(StringUtils.isEmpty(categorytreeJson)){
            //2、redis没有，查数据库； 【回源】（缓存中没有，就需要回到数据的源头要数据）
            List<CategoryTreeVo> categoryTree = baseCategory1Mapper.getCategoryTree();

            //3、序列化：把对象转为json串
            String jsonStr = JSONs.obj2JsonStr(categoryTree);
            //4、保存到远程redis
            redisTemplate.opsForValue().set(RedisConst.INDEXPAGE_CATEGORY_TREE_KEY,jsonStr);

            return categoryTree;
        }

        //5、反序列化：能走到这儿说明redis有这个数据，把json转为List
        return JSONs.jsonStr2Obj(categorytreeJson, new TypeReference<List<CategoryTreeVo>>() {});
    }





    //本地缓存；ehcache、caffine
    Map<String,Object> cache = new ConcurrentHashMap<>();
    public List<CategoryTreeVo> getCategoryTreeWithLocalCache() {
        //1、先查询缓存是否有此数据, categoryTree
        Object categoryTree = cache.get("categoryTree");
        if(categoryTree != null){
            //2、缓存有直接返回
            return (List<CategoryTreeVo>) categoryTree;
        }
        //3、缓存没有查数据库
        List<CategoryTreeVo> data = baseCategory1Mapper.getCategoryTree();
        //4、查到后放入缓存，方便下次使用
        cache.put("categoryTree",data);
        //发送SQL，查询数据，树形封装
        return data;
    }



    @Override
    public CategoryPath getCategoryPath(Long c3Id) {
        return baseCategory1Mapper.getCategoryPath(c3Id);
    }
}




